#coding:utf8
import os
import re

classTem = '''
%s = {}

function %s:Parse(buffer)
	while true do
		local tag = buffer:ReadTag()
		if tag == 0 then
			return
%s
		end
	end
end

function %s:Serialize()
	local buf = {}
	SetIndex(buf, WriteBuffer)
	buf:Init()

	%s
	return buf
end
'''

intTem = '''
		elseif tag == %d then
			self.%s = buffer:ReadInt()
'''

stringTem = '''
		elseif tag == %d then
			self.%s = buffer:ReadString()
'''

messageTem = '''
		elseif tag == %d then
			local msgObj = {}
			SetIndex(msgObj, %s)
			self.%s = buffer:ReadMsg(msgObj)
'''


repeatedTem = '''
		elseif tag == %d then
			if self.%s == nil then
				self.%s = {}
			end
			%s
			table.insert(self.%s, temp)
'''

repeatedInt = '''
			local temp = buffer:ReadInt()
'''
repeatedStr = '''
			local temp = buffer:ReadString()
'''
repeatedMsg = '''
			local msgObj = {}
			SetIndex(msgObj, %s)
			local temp = buffer:ReadMsg(msgObj)
'''


wIntTem = '''
	if self.%s ~= nil then
		buf:WriteInt(%d, self.%s)
	end
'''

wStrTem = '''
	if self.%s ~= nil then
		buf:WriteString(%d, self.%s)
	end
'''
wMsgTem = '''
	if self.%s ~= nil then
		buf:WriteMsg(%d, self.%s)
	end
'''

repeatedWrite = '''
	if self.%s ~= nil then
		for k, v in ipairs(self.%s) do
			%s
		end
	end
'''

rWInt = '''
			buf:WriteInt(%d, v)
'''

rWStr = '''
			buf:WriteString(%d, v)
'''

rWMsg = '''
			buf:WriteMsg(%d, v)
'''

begin = re.compile("\s*message\s*(\w+)\s*\{")
field = re.compile("\s*(optional|required|repeated)\s*(uint64|string|\w+)\s*(\w+)\s*=\s*(\d+)")
end = re.compile("\s*\}")

codes = []

def GenCode(result):
	#f = open(result["type"]+".lua", "w")
	s = ""
	field = ""
	for fi in result["field"]:
		tp = fi[1]
		fn = fi[2]
		fid = int(fi[3])
		if fi[0] == "repeated":
			temp = ""
			if tp == "uint64":
				temp = repeatedInt
			elif tp == "string":
				temp = repeatedStr
			else:
				temp = repeatedMsg % (tp)

			field += repeatedTem % (fid, fn, fn, temp, fn)

		else:
			if tp == "uint64":
				field += intTem % (fid, fi[2])
			elif tp == "string":
				field += stringTem % (fid, fi[2])
			else:
				field += messageTem % (fid, tp, fi[2])


	wfield = ""
	for fi in result["field"]:
		tp = fi[1]
		fid = int(fi[3])
		fn = fi[2]
		if fi[0] == "repeated":
			temp = ""
			if tp == "uint64":
				temp = rWInt % (fid)
			elif tp == "string":
				temp = rWStr % (fid)
			else:
				temp = rWMsg % (fid)
			wfield += repeatedWrite % (fn, fn, temp)
		else:
			if tp == "uint64":
				wfield += wIntTem % (fn, fid, fn)
			elif tp == "string":
				wfield += wStrTem % (fn, fid, fn)
			else:
				wfield += wMsgTem % (fn, fid, fn)

	ct = classTem % (result["type"], result["type"], field, result["type"], wfield)
	codes.append(ct)
	#f.write(ct)
	#f.close()

def HandleFile(f):
	lines = open(f, "r").readlines()
	state = 0
	curType = ''
	result = {}
	for l in lines:
		if state == 0:
			mat = begin.findall(l)
			if len(mat) > 0:
				curType = mat[0]
				state = 1
				print curType
				result = {}
				result["type"] = curType
				result["field"] = []
		elif state == 1:
			mat = field.findall(l)
			if len(mat) > 0:
				curFiled = mat[0]
				print curFiled
				result["field"].append(curFiled)
			else:
				mat = end.findall(l)
				if len(mat) > 0:
					state = 0
					GenCode(result)


def GenFile():
	f = open("PBCode.lua", "w")
	for ct in codes:
		f.write(ct)
	f.close()

def main():
	#HandleFile("test1.proto")
	#测试repeated
	HandleFile("test2.proto")

	GenFile()
main()